package com.zzuli.yxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzuli.yxy.dto.AlbumTree;
import com.zzuli.yxy.entity.Album;
import com.zzuli.yxy.entity.Singer;
import com.zzuli.yxy.entity.Song;
import com.zzuli.yxy.result.R;
import com.zzuli.yxy.util.TXCloudFileUtils;
import com.zzuli.yxy.mapper.AlbumMapper;
import com.zzuli.yxy.mapper.SingerMapper;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.zzuli.yxy.service.SingerService;
import com.zzuli.yxy.service.SongService;

import java.util.ArrayList;
import java.util.List;

/**
 * @auther pony
 * @create 2023-04-04 21:28
 */
@Service
public class SingerServiceImpl extends ServiceImpl<SingerMapper, Singer> implements SingerService {

    @Autowired
    private SingerMapper singerMapper;

    @Autowired
    private AlbumMapper albumMapper;

    @Autowired
    private SongService songService;

    @Autowired
    private AlbumServiceImpl albumService;



    //腾讯云对象存储 路径-访问域名
    private static String url = "https://pony-1312090731.cos.ap-beijing.myqcloud.com/";
    // 头像存储的文件夹
    private static String imgPath = "yxy/images/";

    /**
     * 根据歌手名字查询状态正常歌手信息并返回
     * @param singerName
     * @return
     */
    @Override
    public R getSingerByName(String singerName) {
        //1、根据歌手名查询数据
        LambdaQueryWrapper<Singer> qw = new LambdaQueryWrapper<>();
        qw.eq(Singer::getSingerName, singerName);
        qw.eq(Singer::getSingerStatus, 0);
        List<Singer> singerList = singerMapper.selectList(qw);
        // 如果没有这个歌手返回错误信息，判断查询结果是否为空 （list为空或list没有元素）
        if (singerList==null || singerList.isEmpty()){
            return R.error().message("没有此歌手，请先添加此歌手");
        }
        return R.success().message("根据歌手名查询，歌手信息").data("singerList", singerList);
    }

    /**
     * 根据歌手id 查询对应的歌手专辑信息
     * @param singerId 歌手id
     * @return
     */
    @Override
    public R getAlbumBySingerId(Integer singerId) {
        List<Album> albumList = singerMapper.selectAlbumBySingerId(singerId);
        return R.success().message("根据歌手id，查询歌手的专辑信息").data("albumList", albumList);
    }

    /**
     * 获取歌手管理分页信息
     * @param pageCurrent 当前页
     * @param pageSize 每页条数
     * @param name 关键字 非必传
     * @return
     */
    @Override
    public R getPage(Integer pageCurrent, Integer pageSize, String name) {
        // 1、查询分页信息
        Page<Singer> pageInfo = new Page<>(pageCurrent, pageSize);
        LambdaQueryWrapper<Singer> qw = new LambdaQueryWrapper<>();
        qw.like(name!=null, Singer::getSingerName, name);
        Page<Singer> singerPage = singerMapper.selectPage(pageInfo, qw);
        return R.success().message("歌手分页信息").data("singerPage", singerPage);
    }

    /**
     * 更改歌手当前状态
     * @param id 歌手 id
     * @param status 状态码 0：正常 1：异常
     * @return
     */
    @Override
    public void setStatus(Integer id, Integer status) {
        LambdaUpdateWrapper<Singer> uw = new LambdaUpdateWrapper<>();
        uw.eq(Singer::getSingerId, id);
        uw.set(Singer::getSingerStatus, status);
        singerMapper.update(null, uw);
    }

    /**
     * 添加歌手-添加歌手名和歌手状态
     * @param singer
     * @return
     */
    @Override
    public R addSinger(Singer singer) {
        // 1、添加歌手
        // 获取歌手名的第一个字符
        char[] nameChar = singer.getSingerName().toCharArray();
        HanyuPinyinOutputFormat outputFormat = new HanyuPinyinOutputFormat();
        // 设置音调
        outputFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        // 设置大写
        outputFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        try {
            String[] pinyinList = PinyinHelper.toHanyuPinyinStringArray(nameChar[0], outputFormat);

            if (pinyinList!=null){ //是汉字
                singer.setSingerPyname(pinyinList[0].substring(0, 1));
            } else {
                // java.lang中Character 提供的方法
                singer.setSingerPyname(String.valueOf(Character.toUpperCase(nameChar[0])));
            }
        } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) {
            badHanyuPinyinOutputFormatCombination.printStackTrace();
        }
        int insert = singerMapper.insert(singer);

        if (insert!=1){
            return R.error().message("添加歌手失败，系统错误，请联系管理员！");
        }
        // 2、返回提示信息
        return R.success().message("歌手基本信息添加成功！");
    }

    /**
     * 添加歌手-上传歌手图片
     * @param file 图片
     * @return
     */
    @Override
    public R uploadAddImg(MultipartFile file) {
        //1、上传文件 返回值是 key，即图片重新命名的名字
        String imgName = TXCloudFileUtils.upLoad(imgPath, file);
        //2、拼接 img 访问路径，并写入数据库
        String imgUrl = url  + imgPath + imgName;
        //3、将结果返回给前端
        return R.success().message("歌手图片上传成功").data("singerImgUrl", imgUrl);
    }

    /**
     * 删除云存储桶里的歌手 图片
     * @param singer 待删除歌曲
     */
    public void deleteTXCosSingerImg(Singer singer){
        /*最初爬虫的图片数据没有存到云存储桶 是网易的图片 不需要删，也删不了
        singerImg：http://p1.music.126.net/AAKrMZu-zyunLRqAMO9JlA==/109951166577890720.jpg?param=130y130
        而本系统添加的歌曲时，图片是存储在云存储桶里的，需要删除
        singerImg：https://pony-1312090731.cos.ap-beijing.myqcloud.com/yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
        */
        String singerImg = singer.getSingerImg();

        // 删除云存储桶里的歌曲图片
        if (singerImg!=null && !"".equals(singerImg)){
            //删除云存储桶里的歌曲 图片（网易的不用删）, 只需要判断是否以 https 开头就行
            if (singerImg.startsWith("https")){
                //songImgKey: 20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
                String singerImgKey = singerImg.substring(singerImg.indexOf("images/")+7);
                //文件夹名 + songImgKey yxy/images/20230414093225fcb9570a89b44a1c94421e8239bbe3cf.jpg
                TXCloudFileUtils.del(imgPath+singerImgKey);
            }
        }
    }

    /**
     * 根据歌手 id，删除歌手
     * 既要删除数据库里的关于此歌手的一切信息
     * 1、歌手数据，
     * 2、此歌手的歌曲信息（包括云存储桶的文件信息）
     * 3、此歌手的专辑信息（包括云存储桶的文件信息）
     * 4、歌手和歌曲、歌手和专辑、此歌手歌曲和专辑的关联关系
     * 又要删除 云存储桶里的 图片 数据
     * @param id 歌手id
     * @return
     */
    @Override
    public R deleteSingerById(Integer id) {
        /*1、删除云存储桶里的歌手图片
        查询数据库 得到 歌手信息*/
        LambdaQueryWrapper<Singer> selectQw = new LambdaQueryWrapper<>();
        selectQw.eq(Singer::getSingerId, id);
        Singer selectResult = singerMapper.selectOne(selectQw);
        //2、删除云存储桶里的歌手 图片
        deleteTXCosSingerImg(selectResult);

        //3、删除数据库里歌手基本信息
        LambdaQueryWrapper<Singer> qw = new LambdaQueryWrapper<>();
        qw.eq(Singer::getSingerId, id);
        int deleteResult = singerMapper.delete(qw);

        //4、删除 歌手所有歌曲，并且删除歌手和歌曲的关联关系
        // 查询歌手所有歌曲
        List<Song> songList = singerMapper.selectSongBySingerId(id);
        for (Song song : songList) {
            songService.deleteSongById(song.getSongId());
        }
        //删除歌手 歌曲的关联信息
        singerMapper.deleteSongBySingerId(id);

        //5、删除歌手的全部专辑，并且删除歌手和专辑的关联关系
        // 查询歌手的所有专辑
        List<Album> albumList = singerMapper.selectAlbumBySingerId(id);
        for (Album album : albumList) {
            albumService.deleteAlbumById(album.getAlbumId());
        }
        //删除歌手 专辑的关联信息
        singerMapper.deleteAlbumBySingerId(id);

        //删除歌曲信息
        if (deleteResult==1){
            return R.success().message("歌曲删除成功");
        }
        return R.error().message("歌曲删除失败，系统错误，请联系管理员");
    }

    /**
     * 根据歌手id，查询单个歌手信息
     *
     * @param id 歌手id
     * @return
     */
    @Override
    public R selectOneById(Integer id) {
        LambdaQueryWrapper<Singer> qw = new LambdaQueryWrapper<>();
        qw.eq(Singer::getSingerId, id);
        Singer singer = singerMapper.selectOne(qw);
        return R.success().message("根据id，查询单个歌手数据").data("singer", singer);
    }

    /**
     * 修改歌手基本信息
     * 只需要修改数据库里的 歌手基本信息
     * 对于 数据库里的信息可以使用 update
     * 对于 云存储桶里 歌手图片和歌曲 MP3 文件，先删除再添加，调用的上传的 api，本接口不需要处理
     * @param singer
     * @return
     */
    @Override
    public R updateSinger(Singer singer) {
        //1、修改前先删除原先的数据
        LambdaQueryWrapper<Singer> qw = new LambdaQueryWrapper<>();
        qw.eq(Singer::getSingerId, singer.getSingerId());
        Singer selectOne = singerMapper.selectOne(qw);
        deleteTXCosSingerImg(selectOne);
        /*
         * 根据 歌手id 修改歌手名 、 歌手状态 、歌手介绍
         * 对于 歌手的 图片地址，在调用上传 api 时会修改
         * 这里不需要处理
         * */
        LambdaUpdateWrapper<Singer> uw = new LambdaUpdateWrapper<>();
        uw.eq(Singer::getSingerId, singer.getSingerId());
        uw.set(Singer::getSingerName, singer.getSingerName());
        uw.set(Singer::getSingerStatus, singer.getSingerStatus());
        uw.set(Singer::getSingerRemarks, singer.getSingerRemarks());
        uw.set(Singer::getSingerImg, singer.getSingerImg());
        int updateResult = singerMapper.update(singer, uw);
        if (updateResult==1){
            return R.success().message("歌手修改成功");
        }
        return R.error().message("歌手修改失败，系统错误，请联系管理员");
    }

    /**
     * 批量删除
     * @param ids 歌手 id数组
     * @return
     */
    @Override
    public R deleteSingerBatch(List<Integer> ids) {
        for (Integer id: ids) {
            //1、删除歌手基本信息
            LambdaQueryWrapper<Singer> qw = new LambdaQueryWrapper<>();
            qw.eq(Singer::getSingerId, id);
            int deleteResult = singerMapper.delete(qw);
            //2、删除 歌手所有歌曲，并且删除歌手和歌曲的关联关系
            // 查询歌手所有歌曲
            List<Song> songList = singerMapper.selectSongBySingerId(id);
            for (Song song : songList) {
                songService.deleteSongById(song.getSongId());
            }
            //删除歌手 歌曲的关联信息
            singerMapper.deleteSongBySingerId(id);

            //3、删除歌手的全部专辑，并且删除歌手和专辑的关联关系
            // 查询歌手的所有专辑
            List<Album> albumList = singerMapper.selectAlbumBySingerId(id);
            for (Album album : albumList) {
                albumService.deleteAlbumById(album.getAlbumId());
            }
            //删除歌手 专辑的关联信息
            singerMapper.deleteAlbumBySingerId(id);

            if (deleteResult!=1){
                return R.error().message("批量删除失败，系统错误，请联系管理员");
            }
        }
        return R.success().message("批量删除成功");
    }

    /**
     * 根据歌手id 查询对应的歌手的全部歌曲信息
     * @param singerId 歌手id
     * @return
     */
    @Override
    public R getSongBySingerId(Integer singerId) {
        List<Song> songList = singerMapper.selectSongBySingerId(singerId);
        return R.success().message("根据歌手id 查询对应的歌手的全部歌曲信息").data("songList", songList);
    }

    /**
     * 根据歌手id，查询歌手的所有专辑以及专辑下的所有歌曲
     * @param singerId
     * @return
     */
    @Override
    public R getAlbumSongBySingerId(Integer singerId) {
        ArrayList<AlbumTree> albumTrees = new ArrayList<>();
        //1、查询歌手所有的专辑信息
        List<Album> albumList = singerMapper.selectAlbumBySingerId(singerId);
        for (Album album : albumList) {
            // 封装专辑以及歌曲的树形结构
            AlbumTree albumTree = new AlbumTree();
            // name：即专辑名
            albumTree.setName(album.getAlbumName());
            // children：即专辑下的所有歌的歌名List
            // 根据专辑id，查询专辑下所有歌曲
            List<Song> songList = albumMapper.selectSongByAlbumId(album.getAlbumId());
            // 封装 所有歌名
            ArrayList<AlbumTree> childrenList = new ArrayList<>();
            for (Song song : songList) {
                AlbumTree children = new AlbumTree();
                children.setName(song.getSongName());
                childrenList.add(children);
            }
            albumTree.setChildren(childrenList);
            albumTrees.add(albumTree);
        }
        return R.success().message("歌手的所有专辑及专辑下的所有歌曲数据").data("albumTrees", albumTrees);
    }
}
